//转发测试
//应用例子： rela 间接rpc调用 zone.  利用center 转发

#include <string>
#include "unit_test.h"
#include "log_def.h"
#include "Rpc.h"
#include <unistd.h>
#include "ProtoZoneCenter.h"

using namespace std;
using namespace proto;
using namespace placeholders;


namespace
{


	struct Con
	{
		string m_str;
		uint64_t m_id = 0;
		uint64_t GetId() { return m_id; }
		RpcClient m_client;
	};
	RpcSvr<Con> gCenter = RpcSvr<Con>();
	Con gZone;
	Con gRela;

	int gRunEmptyCnt = 0;
	void Empty()
	{
		UNIT_INFO("Empty");
		gRunEmptyCnt++;
	}
	int Add(int a, int b)
	{
		UNIT_INFO("ReqAdd = %d %d", a, b);
		return a + b;
	}
	string ZoneAdd(int a, int b, std::string s)
	{
		UNIT_INFO("ReqAddStr = %d %d", a, b);
		return string(std::to_string(a + b) + s);
	}

	void Router(std::string zoneFun, const RawPackStr& raw)
	{
		UNIT_INFO("Router %s", zoneFun.c_str());
		uint32_t snid = gCenter.GetCurSnId();
		auto rsp = [snid](const RawPackStr& raw)
		{
			UNIT_INFO("rev zone rsp. snid=%d", snid);
			gCenter.RetEx(gRela, snid, raw);
		};
		gCenter.Call(gZone, rsp, zoneFun, raw);
	}

	void transfer()
	{
		auto send = [](Con& con, const char* data, size_t len)
		{
			con.m_client.Rev(data, len);
		};
		gCenter.Init(send);
		gCenter.RegFun(Router, "Router");

		gZone.m_id = 1;
		gRela.m_id = 2;
		{
			auto sendEx = [](const char* data, size_t len)
			{
				gCenter.Rev(gZone, data, len);
			};
			gZone.m_client.Init(sendEx);
			gZone.m_client.RegFun(ZoneAdd, "ZoneAdd");
			gZone.m_client.RegFun(Empty, "Empty");
		}
		{
			auto sendEx = [](const char* data, size_t len)
			{
				gCenter.Rev(gRela, data, len);
			};
			gRela.m_client.Init(sendEx);
		}

		gCenter.Connect(gZone);
		gCenter.Connect(gRela);

		gZone.m_client.ReqInit();
		gRela.m_client.ReqInit();


		{
			bool isRsp = false;
			{
				auto rsp = [&isRsp](const string& ret)
				{
					isRsp = true;
					UNIT_INFO("ret=%s", ret.c_str());
				};
				gRela.m_client.Call(rsp, "Router", string("ZoneAdd"), 1, 2, string("abc"));
			}
			UNIT_ASSERT(isRsp);
		}
		{
			UNIT_ASSERT(gRunEmptyCnt == 0);
			bool isRsp = false;
			{
				auto rsp = [&isRsp]()
				{
					isRsp = true;
					UNIT_INFO("Empty rsp");
				};
				gRela.m_client.Call(rsp, "Router", string("Empty"));
			}
			UNIT_ASSERT(!isRsp);
			UNIT_ASSERT(gRunEmptyCnt == 1);
		}
	
	}

	

}



UNITTEST(transfer)
{

	transfer();
}

